package net.martus.mail.mbox
{
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.filesystem.File;
	import flash.filesystem.FileMode;
	import flash.filesystem.FileStream;
	import flash.utils.ByteArray;
	
	import net.martus.utils.DirectoryUtils;

	public class MboxParser extends EventDispatcher
	{
		public static const SUCCESS_OPEN:String             = "success_open";
		public static const FAILURE_OPEN:String             = "failure_open";
		
		public static const COMPLETE_CREATE:String          = "complete_create";
		public static const COMPLETE_PARSE:String           = "complete_parse";
		public static const COMPLETE_SAVE:String            = "complete_save";


		private var _mboxFileStream:FileStream;
		private var _from:String;
		
		public function MboxParser()
		{
			this.init();
		}
		
		private function init():void
		{
			this._mboxFileStream = new FileStream();
			this._from = "";
		}
		
		public function set from(from:String):void
		{
			this._from = from;
		}
		
		public function get from():String
		{
			return this._from;
		}
		
		public function create(mbox:File, emls:Array):void
		{
			this._mboxFileStream.open(mbox, FileMode.APPEND);
			dispatchEvent(new Event(MboxParser.SUCCESS_OPEN));
			
			var eml:File;
			var emlStream:FileStream;
			
			for( var i:uint = 0; i < emls.length; i++ )
			{
				eml = emls[i];
				
				if( !eml.exists )
				{
					dispatchEvent(new Event(MboxParser.FAILURE_OPEN));
					continue;
				}
				
				if( eml.size == 0 )
				{
					dispatchEvent(new Event(MboxParser.FAILURE_OPEN));
					continue;
				}
				
				emlStream = new FileStream();
				emlStream.open(eml, FileMode.READ);
				
				this._mboxFileStream.writeUTFBytes("From ");
				this._mboxFileStream.writeUTFBytes(this._from);
				this._mboxFileStream.writeUTFBytes(File.lineEnding);
				
				while( true )
				{
					try
					{
						this._mboxFileStream.writeByte(emlStream.readByte());
					}
					catch( error:Error )
					{
						emlStream.close();
						break;
					}
				}
			}
			
			this._mboxFileStream.close();
			dispatchEvent(new Event(MboxParser.COMPLETE_CREATE));
		}
		
		public function parse(mbox:File):void
		{
			if( !mbox.exists )
			{
				dispatchEvent(new Event(MboxParser.FAILURE_OPEN));
				return;
			}
			
			if( mbox.size == 0 )
			{
				dispatchEvent(new Event(MboxParser.FAILURE_OPEN));
				return;
			}
			
			this._mboxFileStream.open(mbox, FileMode.READ);
			dispatchEvent(new Event(MboxParser.SUCCESS_OPEN));
			
			
			var char:int;
			var count:int = 0;
			var byteArray:ByteArray;
			
			var emlFile:File;
			var emlFileStream:FileStream;
			
			while( true )
			{
				byteArray = new ByteArray();
				
				try
				{
					char = this._mboxFileStream.readByte();
					byteArray.writeByte(char);
					if( char != 70 )
					{ // F
						emlFileStream.writeBytes(byteArray, 0, byteArray.length);
						continue;
					}
					
					char = this._mboxFileStream.readByte();
					byteArray.writeByte(char);
					if( char != 114 )
					{ // r
						emlFileStream.writeBytes(byteArray, 0, byteArray.length);
						continue;
					}
					
					char = this._mboxFileStream.readByte();
					byteArray.writeByte(char);
					if( char != 111 )
					{ // o
						emlFileStream.writeBytes(byteArray, 0, byteArray.length);
						continue;
					}
					
					char = this._mboxFileStream.readByte();
					byteArray.writeByte(char);
					if( char != 109 )
					{ // m
						emlFileStream.writeBytes(byteArray, 0, byteArray.length);
						continue;
					}
					
					char = this._mboxFileStream.readByte();
					byteArray.writeByte(char);
					if( char != 32 )
					{ // space
						emlFileStream.writeBytes(byteArray, 0, byteArray.length);
						continue;
					}
					
					if( emlFileStream != null )
					{
						dispatchEvent(new Event(MboxParser.COMPLETE_SAVE));
						emlFileStream.close();
					}
					
					while( true )
					{
						if( (char = this._mboxFileStream.readByte()) == 10 )
						{
							emlFile = new File();
							emlFile.nativePath = DirectoryUtils.path(mbox.nativePath) + count + ".eml";
							
							count++;
							
							emlFileStream = new FileStream();
							emlFileStream.open(emlFile, FileMode.WRITE);
							break;
						}
					}
				}
				catch( error:Error )
				{
					break;
				}
			}
			
			if( emlFileStream != null )
			{
				dispatchEvent(new Event(MboxParser.COMPLETE_SAVE));
				emlFileStream.close();
			}
			
			this._mboxFileStream.close();
			dispatchEvent(new Event(MboxParser.COMPLETE_PARSE));
		}
	}
}